package com.aiwu;

import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;

import com.aiwu.library.AiWuFileHelper;
import com.aiwu.library.util.IOUtil;
import com.aiwu.library.util.ToastUtil;
import com.aiwu.utils.FileUtils;
import com.aiwu.utils.ZipUtil;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;

public class Util {
    /**
     * 获取后8位id
     *
     * @param romName
     * @return
     */
    public static String getLast8Id(String romName) {
        try {
            return romName.substring(8);
        } catch (StringIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
        return romName;
    }

    /**
     * 获取备份文件的路径
     *
     * @param romName
     * @return
     */
    public static String getBakFilePath(String romName) {
        return Environment.getExternalStorageDirectory() + "/citra-emu/sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/00040000/" + getLast8Id(romName) + "/data/";
    }

    /**
     * 获取备份文件的路径
     *
     * @param romName
     * @return
     */
    public static String getSpecialBakFilePath(String romName) {
        try {
            return Environment.getExternalStorageDirectory() + "/citra-emu/sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/extdata/00000000/" + romName.substring(6, 14) + "/user/";
        } catch (StringIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 从路径中读取id
     * 00040000001d1800
     *
     * @param path /sdcard/citra-emu/sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/00040000/001d1800/content/00000000.app
     */
    public static String getIdFromPath(String path) {
        if (TextUtils.isEmpty(path)) {
            return "";
        }
        if (path.contains("citra-emu")) {
            int startIndex = path.indexOf("title/");
            int endIndex = path.indexOf("/content");
            if (startIndex == -1 || endIndex == -1) {
                return "";
            }
            return path.substring(startIndex + 6, endIndex).replace("/", "");
        } else if (path.contains(AiWuFileHelper.getAiWuSharedDir()) || path.contains("com.aiwu.market")) {
            File file = new File(path);
            return file.getParentFile().getName();
        } else {
            return getGameIdFromFile(path);
        }
    }

    public static String getCheatDir() {
        return getDefaultDir() + "/cheats";
    }

    public static String getDefaultDir() {
        return Environment.getExternalStorageDirectory() + "/citra-emu";
    }

    //Mii是否解压过的标志文件
    public static String getMiiFlagFile() {
        return getDefaultDir() + "/MiiFlag.txt";
    }

    public static String getAesKeysDir() {
        return getDefaultDir() + "/sysdata";
    }

    public static String getFileExtension(String filePath) {
        int extensionStart = filePath.lastIndexOf('.');
        if (extensionStart > 0) {
            return filePath.substring(extensionStart);
        }
        return "";
    }

    public static boolean changeFont(int font) {
        return changeFont(font == PrefsHelper.FONT_ACG);
    }

    /**
     * 切换字库
     *
     * @param isAcg
     * @return
     */
    public static boolean changeFont(boolean isAcg) {
        String fontName = isAcg ? "Font_ACG.zip" : "Font_INIT.zip";
        //把Mii.zip复制到sd卡
        String sdZipPath = IOUtil.copyAssetFile2Out(fontName, Util.getDefaultDir(), true);
        if (sdZipPath == null) {
            //复制出错了
            return false;
        }
        //解压缩zip
        try {
            IOUtil.unzipFile(sdZipPath, Util.getDefaultDir(), true);
            //删除zip
            File zipFile = new File(sdZipPath);
            zipFile.delete();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 返回外部存储的可用大小
     *
     * @return the available size of external storage
     */
    public static long getExternalAvailableSize() {
        return getFsAvailableSize(getSDCardPathByEnvironment());
    }

    public static String getSDCardPathByEnvironment() {
        if (isSDCardEnableByEnvironment()) {
            return Environment.getExternalStorageDirectory().getAbsolutePath();
        }
        return "";
    }

    public static boolean isSDCardEnableByEnvironment() {
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }

    /**
     * 返回文件系统的可用大小。
     *
     * @param anyPathInFs 文件系统中的任何路径
     * @return the available size of file system
     */
    public static long getFsAvailableSize(final String anyPathInFs) {
        if (TextUtils.isEmpty(anyPathInFs)) return 0;
        StatFs statFs = new StatFs(anyPathInFs);
        long blockSize;
        long availableSize;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
            blockSize = statFs.getBlockSizeLong();
            availableSize = statFs.getAvailableBlocksLong();
        } else {
            blockSize = statFs.getBlockSize();
            availableSize = statFs.getAvailableBlocks();
        }
        return blockSize * availableSize;
    }

    /**
     * 从游戏文件里面提取游戏ID
     * 补丁 DLC 跟游戏ID不一样
     *
     * @param in 输入流
     * @return
     * @throws IOException
     */
    public static String getIdFromGameFile(BufferedInputStream in) throws IOException {
        String gameId;
        boolean isFind = false;
        String tagStr = "";
        try {
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            while (-1 != in.read(buffer, 0, buf_size)) {
                String hexString = FileUtils.bytesToHexString(buffer);
                if (!isFind) {
                    if (hexString.contains("4E434348")) {
                        int index = hexString.indexOf("4E434348");
                        if (index + 32 > hexString.length()) {
                            isFind = true;
                            tagStr = hexString;
                        } else {
                            gameId = findGameId(hexString);
                            try {
                                in.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            return gameId;
                        }
                    }
                } else {
                    hexString = tagStr + hexString;
                    gameId = findGameId(hexString);
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return gameId;
                }
            }
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        }

    }


    private static String findGameId(String str) {
        int index = str.indexOf("4E434348");
        String id = str.substring(index + 16, index + 32);
        String gameId = "";
        for (int i = 8; i > 0; i--) {
            gameId += id.substring(id.length() - 2);
            id = id.substring(0, id.length() - 2);
        }
        return gameId;
    }

    /**
     * 判断ZIP里面是否包含该游戏的补丁或者DLC
     *
     * @return
     */
    public static boolean isSameGameIdFromZip(String filePath, String gameId) {
        String temporaryPath = Environment.getExternalStorageDirectory() + "/citra-emu/.unzip_temporary/";
        File testFile = new File(temporaryPath);
        if (!testFile.exists()) {
            testFile.mkdirs();
        }
        try {
            ZipUtil.unzip(filePath, temporaryPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        temporaryPath = temporaryPath + "sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/";
        File dlcPathFile = new File(temporaryPath);
        if (!dlcPathFile.exists()) {
            return false;
        }
        List<String> fileNameList = FileUtils.getAllFilesName(temporaryPath);
        if (fileNameList.size() == 0) {
            return false;
        }
        for (String name : fileNameList) {
            String gameFilePath = temporaryPath + name + "/" + gameId;
            File pathFile = new File(gameFilePath);
            if (pathFile.exists()) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }


    /**
     * 将临时文件里面的DLC 补丁文件移动到游戏文件夹里面
     *
     * @param gameId
     */
    public static void moveDLCOrPatchFileFromUnZipTemporaryFile(String gameId) {
        String temporaryPath = Environment.getExternalStorageDirectory() + "/citra-emu/.unzip_temporary/sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/";
        String gameFilePath = Environment.getExternalStorageDirectory() + "/citra-emu/sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/";
        File file = new File(temporaryPath);
        if (!file.exists()) {
            ToastUtil.toast("未知错误，请重新选择文件");
            return;
        }

        List<String> fileNameList = FileUtils.getAllFilesName(temporaryPath);
        for (String name : fileNameList) {
            String temporaryFullPath = temporaryPath + name + "/" + gameId;
            String gameFileFullPath = gameFilePath + name + "/" + gameId;
            File temporaryFullFile = new File(temporaryFullPath);
            if (temporaryFullFile.exists()) {
                FileUtils.copyFolder(temporaryFullPath, gameFileFullPath);
            }
        }

    }

    /**
     * 删除临时文件
     */
    public static void deleteUnZipTemporaryFile() {
        String path = Environment.getExternalStorageDirectory() + "/citra-emu/.unzip_temporary/";
        FileUtils.deleteDirWithFile(new File(path));
    }

    /**
     * 从文件中取16位游戏ID
     *
     * @param filePath
     * @return
     */
    public static String getGameIdFromFile(String filePath) {
        if (TextUtils.isEmpty(filePath)) {
            return "";
        }
        if (filePath.endsWith(".zip")) {//压缩包
            ZipFile zip = null;
            try {
                zip = new ZipFile(filePath, "GBK");
                //获取压缩包的所有文件
                Enumeration<ZipEntry> entries = zip.getEntries();
                while (entries.hasMoreElements()) {
                    ZipEntry entry = (ZipEntry) entries.nextElement();
                    String id = getIdFromGameFile(new BufferedInputStream(zip.getInputStream(entry)));
                    if (is3DSGameId(id)) {
                        return id;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (zip != null) {
                    try {
                        zip.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {//单文件
            try {
                String id = getIdFromGameFile(new BufferedInputStream(new FileInputStream(filePath)));
                if (is3DSGameId(id)) {
                    return id;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 判断16位ID是否是游戏
     *
     * @param id
     * @return
     */
    public static boolean is3DSGameId(String id) {
        return id.startsWith("00040000");
    }
}
